package fr.inserm.umr915.vcfserver.bio;

import java.util.Comparator;

import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;

import fr.inserm.umr915.vcfserver.lang.LoopControl;

public class Segment
	implements Comparable<Segment>
	{
	private String chromosome;
	private int chromStart;
	private int chromEnd;
	
	public Segment(String chromosome, int chromStart,int chromEnd)
		{
		this.chromosome = chromosome;
		this.chromStart = chromStart;
		this.chromEnd = chromEnd;
		}
	
	public boolean overlap(Segment s)
		{
		return this.getChromosome().equals(s.getChromosome()) &&
			!(
			  this.getChromEnd()<= s.getChromStart() ||
			  s.getChromEnd()<=this.getChromStart()
			);
		}
	
	public static LoopControl scanner(Segment query,Segment cursor)
		{
		int i=cursor.getChromosome().compareTo(query.getChromosome());
		if(i<0) return LoopControl.CONTINUE;
		if(i>0) return LoopControl.BREAK;
		if(cursor.getChromEnd()<=query.getChromStart()) return LoopControl.CONTINUE;
		if(cursor.getChromStart()>= query.getChromEnd()) return LoopControl.BREAK;
		return  LoopControl.OK;
		}
	
	
	
	public String getChromosome() {
		return chromosome;
		}
	public int getChromStart()
		{
		return chromStart;
		}
	
	public int getChromEnd()
		{
		return chromEnd;
		}
	
	public int length()
		{
		return getChromEnd()-getChromStart();
		}
	
	@Override
	public int hashCode()
		{
		final int prime = 31;
		int result = 1;
		result = prime * result + chromosome.hashCode();
		result = prime * result + chromStart;
		result = prime * result + chromEnd;
		return result;
		}
	
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Segment other = (Segment) obj;
		return 	chromStart==other.chromStart &&
				chromEnd==other.chromEnd && 
				chromosome.equals(other.chromosome);
		}
	
	@Override
	public int compareTo(Segment o)
		{
		int i=getChromosome().compareTo(o.getChromosome());
		if(i!=0) return i;
		i=getChromStart()-o.getChromStart();
		if(i!=0) return i;
		return getChromEnd()-o.getChromEnd();
		}
	
	@Override
	public String toString()
		{
		return getChromosome()+":"+getChromStart()+"-"+getChromEnd();
		}
	
	
	public static class Binding extends TupleBinding<Segment>
		{
		private Chromosomes chromosomes;
		public Binding(Chromosomes chromosomes)
			{
			this.chromosomes=chromosomes;
			}
		
		@Override
		public Segment entryToObject(TupleInput in)
			{
			byte c=in.readByte();
			String chrom= this.chromosomes.getNameById(c);
			int n1=in.readInt();
			int n2=in.readInt();
			return new Segment(chrom, n1,n2);
			}
		
		@Override
		public void objectToEntry(Segment o, TupleOutput out)
			{
			byte b= this.chromosomes.getIdByName(o.getChromosome());
			out.writeByte(b);
			out.writeInt(o.getChromStart());
			out.writeInt(o.getChromEnd());
			}
		}
	
	
	public static class Sorter implements Comparator<byte[]>
		{
		
		public Sorter()
			{
			}
		@Override
		public int compare(byte[] o1, byte[] o2)
			{
			TupleInput in1=new TupleInput(o1);
			TupleInput in2=new TupleInput(o2);
			
			byte c1= in1.readByte();
			byte c2= in2.readByte();
			if(c1!=c2) return c1-c2;
			
			int pos1= in1.readInt();
			int pos2= in2.readInt();
			if(pos1!=pos2) return pos1-pos2;
			
			pos1= in1.readInt();
			pos2= in2.readInt();
			if(pos1!=pos2) return pos1-pos2;
			
			return 0;
			}
		}
	}
